package cn.chinaunicom.sdsi.frm.workflow.task.controller;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import cn.chinaunicom.sdsi.frm.workflow.bean.HistoicFlowVO;
import cn.chinaunicom.sdsi.frm.workflow.bean.TaskVO;
import cn.chinaunicom.sdsi.frm.workflow.bean.jsonreturn.PageReturnData;
import cn.chinaunicom.sdsi.frm.workflow.bean.jsonreturn.ReturnData;
import cn.chinaunicom.sdsi.frm.workflow.task.service.ActTaskService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@RestController("workflowRestController")
@RequestMapping(value = "/workflowrest")
public class WorkflowRestController {

	private static final Log log = LogFactory.getLog(WorkflowRestController.class);

	/**
	 * 工作流任务相关的业务逻辑组件
	 */
	private ActTaskService actTaskService;

	/**
	 * 翻页查找待办任务
	 * 
	 * @param vo
	 *            查询条件封装
	 * @param start
	 *            开始条数
	 * @param length
	 *            每页长度
	 * @return 微服务规范分页实体
	 */
	@RequestMapping(value = "/tasktodo/{userId}", method = RequestMethod.POST)
	public PageReturnData<JSONObject> searchToDo4Page(@RequestBody TaskVO vo, @PathVariable("userId") String userId,
			int start, int length) {

		String[] assigneeIds = { userId };
		vo.setAssigneeIds(assigneeIds);
		log.debug("WorkflowController.searchToDo4Page{}:start:" + start + ";length:" + length + ";vo" + vo);

		JSONObject result = actTaskService.listToDo4Page(vo, start, length);
		PageReturnData<JSONObject> prd = new PageReturnData<JSONObject>();

		@SuppressWarnings("unchecked")
		List<JSONObject> dataRows = (List<JSONObject>) JSONArray.toCollection(result.getJSONArray("data"),
				JSONObject.class);
		int totalResult = result.getInt("recordsFiltered");

		prd.setDataRows(dataRows);
		prd.setPageSize(length);
		prd.setCurrentPage(start / length + 1);
		prd.setTotalResult(totalResult);
		prd.setTotalPage(totalResult / length + 1);

		prd.setRetCode(1);
		prd.setRetVal("success");

		return prd;
	}

	/**
	 * 翻页已办任务
	 * 
	 * @param vo
	 *            查询条件封装
	 * @param start
	 *            开始条数
	 * @param length
	 *            每页长度
	 * @return 微服务规范分页实体
	 */
	@RequestMapping(value = "/taskhasdone/{userId}", method = RequestMethod.POST)
	public PageReturnData<JSONObject> searchHasDone4Page(@RequestBody TaskVO vo, @PathVariable("userId") String userId,
			int start, int length) {

		String[] assigneeIds = { userId };
		vo.setAssigneeIds(assigneeIds);
		log.debug("WorkflowController.listHasDone4Page{}:start:" + start + ";length:" + length + ";vo" + vo);

		JSONObject result = actTaskService.listHasDone4Page(vo, start, length);
		PageReturnData<JSONObject> prd = new PageReturnData<JSONObject>();

		@SuppressWarnings("unchecked")
		List<JSONObject> dataRows = (List<JSONObject>) JSONArray.toCollection(result.getJSONArray("data"),
				JSONObject.class);
		int totalResult = result.getInt("recordsFiltered");

		prd.setDataRows(dataRows);
		prd.setPageSize(length);
		prd.setCurrentPage(start / length + 1);
		prd.setTotalResult(totalResult);
		prd.setTotalPage(totalResult / length + 1);

		prd.setRetCode(1);
		prd.setRetVal("success");

		return prd;
	}

	/**
	 * 简退-回退操作
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @param taskId
	 *            当前任务ID
	 * @param comment
	 *            流程意见
	 * @return 返回信息
	 */
	@RequestMapping(value = "/pushprocesstostart/{processInstanceId}/{taskId}", method = RequestMethod.POST)
	public ReturnData<String> pushProcessToStart(@PathVariable("processInstanceId") String processInstanceId,
			@PathVariable("taskId") String taskId, String comment) {

		boolean success = actTaskService.backForQuick(processInstanceId, taskId, comment);

		ReturnData<String> rd = new ReturnData<String>();
		List<String> list = new ArrayList<String>(1);

		rd.setDataRows(list);
		if (!success) {
			rd.setRetCode(0);
			rd.setRetVal("error, not success");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 简退-推进操作
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @param taskId
	 *            当前任务ID
	 * @param comment
	 *            流程意见
	 * @return 返回信息
	 */
	@RequestMapping(value = "/pushprocessreturnback/{processInstanceId}/{taskId}", method = RequestMethod.POST)
	public ReturnData<String> pushProcessReturnBack(@PathVariable("processInstanceId") String processInstanceId,
			@PathVariable("taskId") String taskId, String comment) {

		boolean success = actTaskService.pushForQuick(processInstanceId, taskId, comment);

		ReturnData<String> rd = new ReturnData<String>();
		List<String> list = new ArrayList<String>(1);

		rd.setDataRows(list);
		if (!success) {
			rd.setRetCode(0);
			rd.setRetVal("error, not success");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 实现任务转派
	 * 
	 * @param processInstanceId
	 *            流程实例
	 * @param taskId
	 *            当前任务ID
	 * @param assignee
	 *            目标处理人
	 * @param comment
	 *            用户审批意见
	 * @return 返回信息
	 */
	@RequestMapping(value = "/transfertask/{processInstanceId}/{taskId}/{assignee}", method = RequestMethod.POST)
	public ReturnData<String> transferTask(@PathVariable("processInstanceId") String processInstanceId,
			@PathVariable("taskId") String taskId, @PathVariable("assignee") String assignee, String comment) {

		String newTaskId = actTaskService.transferTask(taskId, processInstanceId, assignee, comment);

		ReturnData<String> rd = new ReturnData<String>();
		List<String> list = new ArrayList<String>(1);

		rd.setDataRows(list);
		if ("".equals(newTaskId)) {
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available url");
		} else {
			list.add(newTaskId);
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 获取待办页面业务主页面及参数
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @param taskId
	 *            任务ID
	 * @param taskDefinitionKey
	 *            任务key
	 * @return 微服务规范分页实体
	 */
	@RequestMapping(value = "/tasktodopath/{processInstanceId}/{taskDefinitionKey}/{taskId}")
	public ReturnData<JSONObject> findTaskToDoPath(@PathVariable("processInstanceId") String processInstanceId,
			@PathVariable("taskId") String taskId, @PathVariable("taskDefinitionKey") String taskDefinitionKey) {

		// 临时存储对象
		JSONObject obj = actTaskService.findTaskUrlAndHandleParam(processInstanceId, taskId, taskDefinitionKey, true);
		log.debug("return the obj :" + obj);

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		List<JSONObject> list = new ArrayList<JSONObject>(1);

		rd.setDataRows(list);
		if (obj == null) {
			list.add(new JSONObject());
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available url");
		} else {
			list.add(obj);
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 获取已办页面业务主页面及参数
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @param taskDefinitionKey
	 *            任务key
	 * @param taskId
	 *            任务ID
	 * @return 微服务规范分页实体
	 */
	@RequestMapping(value = "/taskhasdonepath/{processInstanceId}/{taskDefinitionKey}/{taskId}")
	public ReturnData<JSONObject> findTaskHasDonePath(@PathVariable("processInstanceId") String processInstanceId,
			@PathVariable("taskDefinitionKey") String taskDefinitionKey, @PathVariable("taskId") String taskId) {

		// 临时存储对象
		JSONObject obj = actTaskService.findTaskUrlAndHandleParam(processInstanceId, taskId, taskDefinitionKey, false);
		log.debug("return the obj :" + obj);

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		List<JSONObject> list = new ArrayList<JSONObject>(1);

		rd.setDataRows(list);
		if (obj == null) {
			list.add(new JSONObject());
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available url");
		} else {
			list.add(obj);
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 获取流程实例的任务流转历史
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @return 流转历史集合
	 */
	@RequestMapping(value = "/histoicflow/{processInstanceId}")
	public ReturnData<HistoicFlowVO> histoicFlow(@PathVariable("processInstanceId") String processInstanceId) {

		List<HistoicFlowVO> histoicFlowList = actTaskService.findHistoicFlowList(processInstanceId);

		ReturnData<HistoicFlowVO> rd = new ReturnData<HistoicFlowVO>();

		rd.setDataRows(histoicFlowList);
		if (histoicFlowList.size() <= 0) {
			rd.setRetCode(0);
			rd.setRetVal("error, can't find taskRecord");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}

		return rd;
	}

	/**
	 * 绘制流程图
	 * 
	 * @param response
	 *            最终向此回复输出图像
	 * @param processInstanceId
	 *            流程实例ID
	 * @return
	 */
	@RequestMapping(value = "/flowchart/{processInstanceId}", method = RequestMethod.GET)
	public void showDiagram(@PathVariable("processInstanceId") String processInstanceId, HttpServletResponse response) {

		log.debug("The processInstanceId is : " + processInstanceId);
		OutputStream out = null;
		try {
			response.setContentType("multipart/form-data;charset=utf8");
			out = response.getOutputStream();
			out.write(actTaskService.getDiagram(processInstanceId));
			out.flush();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}

		log.debug("showDiagram done .");
	}

	/**
	 * 用户审批点击通过或回退时加载可选环节
	 * 
	 * @param taskId
	 *            当前任务ID
	 * @param handleType
	 *            处理类型（1、通过2、退回）
	 * @param passSelect
	 *            分支环节选取环节
	 * @return 可选环节键值对
	 */
	@RequestMapping(value = "/tasklink/{taskId}/{handleType}/branch/{passSelect}")
	public ReturnData<JSONObject> selectLink(@PathVariable("taskId") String taskId,
			@PathVariable("handleType") int handleType, @PathVariable("passSelect") int passSelect) {

		JSONArray array = actTaskService.findLinkIds(taskId, handleType, passSelect);

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		@SuppressWarnings("unchecked")
		List<JSONObject> dataRows = (List<JSONObject>) JSONArray.toCollection(array, JSONObject.class);

		rd.setDataRows(dataRows);
		if (dataRows.size() <= 0) {
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available link");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}
		log.debug("return the object :" + rd);

		return rd;
	}

	/**
	 * 用户审批点击通过或回退时加载可选环节
	 * 
	 * @param processDefinitionKey
	 *            流程定义key
	 * @param passSelect
	 *            分支环节选取环节
	 * @return 可选环节键值对
	 */
	@RequestMapping(value = "/tasklinkforstart/{processDefinitionKey}/{passSelect}")
	public ReturnData<JSONObject> selectLinkForStart(@PathVariable("processDefinitionKey") String processDefinitionKey,
			@PathVariable("passSelect") int passSelect) {

		JSONArray array = actTaskService.findLinkIds(processDefinitionKey, passSelect);

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		@SuppressWarnings("unchecked")
		List<JSONObject> dataRows = (List<JSONObject>) JSONArray.toCollection(array, JSONObject.class);

		rd.setDataRows(dataRows);
		if (dataRows.size() <= 0) {
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available link");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}
		log.debug("return the object :" + rd);

		return rd;
	}

	/**
	 * 根据所在环节查询需展现的自定义标签
	 * 
	 * @param processDefinitionId
	 *            流程定义数据主键
	 * @param taskDefinitionKey
	 *            环节定义KEY
	 * @param todo
	 *            是否为待办，否则为已办
	 * @return 信息集合
	 */
	@RequestMapping(value = "/taburls/{processDefinitionId}/{taskDefinitionKey}/{todo}")
	public ReturnData<JSONObject> addTabUrls(@PathVariable("processDefinitionId") String processDefinitionId,
			@PathVariable("taskDefinitionKey") String taskDefinitionKey, @PathVariable("todo") boolean todo) {

		JSONArray array = actTaskService.parseTabUrls(processDefinitionId, taskDefinitionKey, todo);

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		@SuppressWarnings("unchecked")
		List<JSONObject> dataRows = (List<JSONObject>) JSONArray.toCollection(array, JSONObject.class);

		rd.setDataRows(dataRows);
		if (dataRows.size() <= 0) {
			rd.setRetCode(0);
			rd.setRetVal("error, can't find available tabs");
		} else {
			rd.setRetCode(1);
			rd.setRetVal("success");
		}
		log.debug("return the tabUrls :" + rd);

		return rd;
	}

	/**
	 * 根据实例ID及流程定义与环节定义key获取处理人可选列表
	 * 
	 * @param processDefinitionKey
	 *            流程实例定义key
	 * @param taskDefinitionKey
	 *            目标环节定义key
	 * @param processInstanceId
	 *            流程实例ID
	 * @return 待办人数据
	 */
	@Deprecated
	@RequestMapping(value = "/assignee/{processDefinitionKey}/{taskDefinitionKey}/{processInstanceId}")
	public ReturnData<JSONObject> selectAssignee(@PathVariable("processDefinitionKey") String processDefinitionKey,
			@PathVariable("taskDefinitionKey") String taskDefinitionKey,
			@PathVariable("processInstanceId") String processInstanceId) {

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		JSONObject obj1 = new JSONObject();
		obj1.element("label", "老板甲");
		obj1.element("value", "10001");
		JSONObject obj2 = new JSONObject();
		obj2.element("label", "老板丙");
		obj2.element("value", "10001");

		List<JSONObject> dataRows = new ArrayList<JSONObject>();
		dataRows.add(obj1);
		dataRows.add(obj2);
		rd.setDataRows(dataRows);
		rd.setRetCode(1);
		rd.setRetVal("success");
		log.debug("return the object :" + rd);

		return rd;
	}

	/**
	 * 根据实例ID及流程定义与环节定义key获取处理人可选列表
	 * 
	 * @param processDefinitionKey
	 *            流程实例定义key
	 * @param taskDefinitionKey
	 *            目标环节定义key
	 * @return 待办人数据
	 */
	@Deprecated
	@RequestMapping(value = "/assigneeforstart/{processDefinitionKey}/{taskDefinitionKey}")
	public ReturnData<JSONObject> selectAssigneeForStart(
			@PathVariable("processDefinitionKey") String processDefinitionKey,
			@PathVariable("taskDefinitionKey") String taskDefinitionKey) {

		ReturnData<JSONObject> rd = new ReturnData<JSONObject>();
		JSONObject obj1 = new JSONObject();
		obj1.element("label", "员工甲");
		obj1.element("value", "10001");
		JSONObject obj2 = new JSONObject();
		obj2.element("label", "员工乙");
		obj2.element("value", "10001");

		List<JSONObject> dataRows = new ArrayList<JSONObject>();
		dataRows.add(obj1);
		dataRows.add(obj2);
		rd.setDataRows(dataRows);
		rd.setRetCode(1);
		rd.setRetVal("success");
		log.debug("return the object :" + rd);

		return rd;
	}

	/**
	 * 获取可选择的流程类型
	 * 
	 * @return
	 *//*
		 * @RequestMapping("/selectProcessType")
		 * 
		 * @ResponseBody public JSONObject selectProcessType() {
		 * 
		 * SysUser sso = SysUserUtils.getUser(); String busiGroupId =
		 * sso.getBusiGroupId();
		 * 
		 * JSONObject obj =
		 * this.getActTaskService().findProcessType(busiGroupId);
		 * 
		 * log.debug("return the object :" + obj); return obj; }
		 */

	@Autowired
	public void setActTaskService(ActTaskService actTaskService) {
		this.actTaskService = actTaskService;
	}
}
